package jprint.base.label;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.imageio.ImageIO;
import jprint.base.AppContext;
import jprint.base.util.JsonUtil;

/**
 * @author zw-zheng
 * Created on 2020-12-15
 */
public class FontService {

    private static FontService sInstance;
    private static Map<String, String> fontMapping;
    private List<String> fontNames = new ArrayList<>();

    private static class TextStyle {

        final String text;
        final String fontFamily;
        int fontSize = 11;
        final boolean bold;
        final boolean italic;

        TextStyle(String text, String fontFamily, int fontSize, boolean bold, boolean italic) {
            this.text = text;
            this.fontFamily = fontFamily;
            this.fontSize = fontSize;
            this.bold = bold;
            this.italic = italic;
        }
    }

    @SuppressWarnings("unchecked")
    private FontService(AppContext appContext) {
        if (fontMapping == null) {
            try {
                File fontJson = new File(appContext.getWebRoot(), "font.json");
                Map<String, String> map =
                    JsonUtil.fromJsonString(new InputStreamReader(new FileInputStream(fontJson),
                                                                  StandardCharsets.UTF_8),
                                            Map.class);
                fontMapping = new HashMap<>(map);
                System.out.println(fontMapping);
            } catch (FileNotFoundException ignored) {
                // ignored
            }
        }
    }

    public static FontService getInstance(AppContext appContext) {
        if (sInstance == null) sInstance = new FontService(appContext);
        return sInstance;
    }

    public List<String> fontList() {
        if (fontNames.isEmpty()) {
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            for (String name : ge.getAvailableFontFamilyNames(Locale.SIMPLIFIED_CHINESE)) {
                // 仅显示中文字体名
                // if (Strings.isChineseOnly(name)) fontNames.add(name);
                // System.out.println("font: " + name);
                if (fontMapping.containsKey(name)) fontNames.add(name);
            }
        }
        return fontNames;
    }

    public byte[] drawTextAsImage(Map<String, List<String>> params) {
        String text = params.get("text").get(0);
        String fontFamily = params.get("fontFamily").get(0);
        int fontSize = Integer.parseInt(params.get("fontSize").get(0));
        boolean bold = "true".equals(params.get("bold").get(0));
        int width = Integer.parseInt(params.get("width").get(0));
        int height = Integer.parseInt(params.get("height").get(0));
        TextStyle style = new TextStyle(text, fontFamily, fontSize, bold, false);
        BufferedImage image = drawTextAsImage(style, width, height);
        ByteArrayOutputStream out = new ByteArrayOutputStream(4 * 1024);
        try {
            ImageIO.write(image, "png", out);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    public BufferedImage drawTextAsImage(TextStyle style, int width, int height) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_565_RGB);
        Graphics2D g2d = image.createGraphics();
        // ---------- 增加下面的代码使得背景透明 -----------------
        image = g2d.getDeviceConfiguration()
            .createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = image.createGraphics();
        //消除文字锯齿
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                             RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        //消除画图锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.BLACK);
        float fontSize = 4 * (style.fontSize + 0.25f) / 3;
        int fontStyle = Font.PLAIN;
        if (style.bold) fontStyle |= Font.BOLD;
        if (style.italic) fontStyle |= Font.ITALIC;
        Font font = new Font(style.fontFamily, fontStyle, Math.round(fontSize));
        g2d.setFont(font);
        g2d.drawString(style.text, 0, height * 3 / 4);
        g2d.dispose();
        return image;
    }
}
